% write_basic_term_pstree.pro

% intended for inclusion in module write_basic_term

:- style_check(-atom).          % allow long atoms


%------------------------------------------------------------------------------
% WRITE A BASIC TERM AS LaTeX pstree FORMAT
%------------------------------------------------------------------------------
%
% Example LaTeX for an occurrence labelled subterm tree diagram from Lloyd 2003.
%
%   (((append x) []) (process x))
%
% \newcommand{\lterm}[2]{\TR{#2}\tlput{\ensuremath{\scriptstyle{#1}}}}
% \newcommand{\rterm}[2]{\TR{#2}\trput{\ensuremath{\scriptstyle{#1}}}}
%
% \pstree[nodesep=2pt,levelsep=15ex,arrows=->]{\TR{$(((\text{append}\ x)\ [])\ (\text{process}\ x))$}}{
%     \pstree{ \lterm{1}{$((\text{append}\ x)\ [])$} }{
%         \pstree{ \lterm{1}{$(\text{append}\ x)$} }{
%             \lterm{1}{$\text{append}$}
%             \rterm{2}{$x$}
%         }
%         \rterm{2}{$[]$}
%     }
%     \pstree{ \rterm{2}{$(\text{process}\ x)$} }{
%         \lterm{1}{$\text{process}$}
%         \rterm{2}{$x$}
%     }
% }
%

% TO-DO: could use tabular environment in nodes to autowrap overly wide lines
%        eg.  \TR{\begin{tabular}{c} You are \\ here \end{tabular}}



%   write_basic_term_pstree(+Term)
%
%   write latex pstree text describing term
%   Term is a basic term represented as a typed prolog term
%
write_basic_term_pstree(Term) :-
    format('\
\\documentclass[a4paper]{article}
\\usepackage{fullpage}

\\usepackage{pstricks,pst-node,pst-tree,graphics}
\\usepackage{amsmath,amssymb}

\\newcommand{\\lterm}[2]{\\TR{\\small \\ensuremath{#2}}\\tlput{\\tiny \\ensuremath{\\scriptstyle{#1}}}}
\\newcommand{\\rterm}[2]{\\TR{\\small \\ensuremath{#2}}\\trput{\\tiny \\ensuremath{\\scriptstyle{#1}}}}

\\begin{document}

%\\rotatebox{90}{%
'),
    basic_term_pstree(Term, '',l),
    format('\
%}

\\end{document}
'   ).



basic_term_pstree(X::T, Num,Dir) :-
    X =.. [abstraction|Ps],
    !,
%    memberchk(P::N-Q::M, Ps),
%    length(Ps,Len),
    format('\\pstree[nodesep=4pt,levelsep=15ex,arrows=->,linestyle=solid,linewidth=0.25pt]{ \\~wterm{~w}{',
           [Dir,Num]),
    write_basic_term(latex, X::T),
    format('} }{\n'),
    %
    length(Ps,L),
    numlist(1,L,Nums),
    forall(
        member(ItemNum,Nums),
        (
         nth1(ItemNum,Ps,P-M),
         N1 is ItemNum * 2 - 1,
         (N1 > L
         -> ItemDir = r
         ;  ItemDir = l
         ),
         basic_term_pstree(P, 1,ItemDir),
         %
         N2 is ItemNum * 2,
         (N2 > L
         -> ItemDir2 = r
         ;  ItemDir2 = l
         ),
         basic_term_pstree(M, 2,ItemDir2)
        )
    ),
    %
    format('}\n').

basic_term_pstree(X::T, Num,Dir) :-
    X =.. [tuple|Ps],
    !,
    format('\\pstree[nodesep=4pt,levelsep=15ex,arrows=->,linestyle=solid,linewidth=0.25pt]{ \\~wterm{~w}{',
           [Dir,Num]),
    write_basic_term(latex, X::T),
    format('} }{\n'),
    %
    length(Ps,L),
    numlist(1,L,Nums),
    Middle is L / 2,
    forall(
        member(ItemNum,Nums),
        (
         nth1(ItemNum,Ps,P),
         (ItemNum > Middle
         -> ItemDir = r
         ;  ItemDir = l
         ),
         basic_term_pstree(P, ItemNum,ItemDir)
        )
    ),
    %
    format('}\n').

basic_term_pstree(X::T, Num,Dir) :-
    X =.. [C|Ps],
    !,
    % constructor
    length(Ps,L),
    (L == 0
    ->  (
         format('\\~wterm{~w}{', [Dir,Num]),
         write_basic_term(latex, X::T),
         format('}\n')
        )
    ;
        (
         format('\\pstree[nodesep=4pt,levelsep=15ex,arrows=->,linestyle=solid,linewidth=0.25pt]{ \\~wterm{~w}{',
           [Dir,Num]),
         write_basic_term(latex, C::T),
         format('} }{\n'),
         %
         numlist(1,L,Nums),
         Middle is L / 2,
         forall(
            member(ItemNum,Nums),
            (
             nth1(ItemNum,Ps,P),
             (ItemNum > Middle
             -> ItemDir = r
             ;  ItemDir = l
             ),
             basic_term_pstree(P, ItemNum,ItemDir)
            )
         ),
         format('}\n')
        )
    ).

